package atuoCode;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import com.kcwx.common.constant.Constants;
import com.kcwx.common.constant.GenConstants;
import com.kcwx.common.core.text.CharsetKit;
import com.kcwx.common.exception.ServiceException;
import com.kcwx.common.utils.StringUtils;
import com.kcwx.common.utils.spring.SpringUtils;
import com.kcwx.generator.config.GenConfig;
import com.kcwx.generator.domain.GenTable;
import com.kcwx.generator.domain.GenTableColumn;
import com.kcwx.generator.service.IGenTableColumnService;
import com.kcwx.generator.service.IGenTableService;
import com.kcwx.generator.util.GenUtils;
import com.kcwx.generator.util.VelocityInitializer;
import com.kcwx.generator.util.VelocityUtils;

public class MybatisGenrator {

	public static void main(String[] args) {
		importTableSave();
	}

	public static void importTableSave() {
		String[] tableNames = "cz_01,cz_02".split(",");
		String database = "mysql";

		// 查询表信息
		List<GenTable> tableList = SpringUtils.getBean(IGenTableService.class).selectDbTableListByNames(database,
				tableNames);
		try {
			String operName = "sysadmin";
			for (GenTable table : tableList) {
				String tableName = table.getTableName();
				GenUtils.initTable(table, operName);
				// 保存列信息
				List<GenTableColumn> genTableColumns = SpringUtils.getBean(IGenTableColumnService.class)
						.selectDbTableColumnsByName(database, tableName);
				for (GenTableColumn column : genTableColumns) {
					GenUtils.initColumnField(column, table);
				}
				table.setColumns(genTableColumns);
				// 生成代码（自定义路径）
				generatorCode(table);
			}
		} catch (Exception e) {
			throw new ServiceException("导入失败：" + e.getMessage());
		}
	}

	public static void generatorCode(GenTable table) {
		// 设置主子表信息
		setSubTable(table);
		// 设置主键列信息
		setPkColumn(table);

		VelocityInitializer.initVelocity();

		VelocityContext context = VelocityUtils.prepareContext(table);

		// 获取模板列表
		List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
		for (String template : templates) {
			if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) {
				// 渲染模板
				StringWriter sw = new StringWriter();
				Template tpl = Velocity.getTemplate(template, Constants.UTF8);
				tpl.merge(context, sw);
				try {
					String path = getGenPath(table, template);
					FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8);
				} catch (IOException e) {
					throw new ServiceException("渲染模板失败，表名：" + table.getTableName());
				}
			}
		}
	}

	/**
	 * 设置主子表信息
	 * 
	 * @param table 业务表信息
	 */
	public static void setSubTable(GenTable table) {
		table.setSubTable(null);
	}

	/**
	 * 设置主键列信息
	 * 
	 * @param table 业务表信息
	 */
	public static void setPkColumn(GenTable table) {
		for (GenTableColumn column : table.getColumns()) {
			if (column.isPk()) {
				table.setPkColumn(column);
				break;
			}
		}
		if (StringUtils.isNull(table.getPkColumn())) {
			table.setPkColumn(table.getColumns().get(0));
		}
		if (GenConstants.TPL_SUB.equals(table.getTplCategory())) {
			for (GenTableColumn column : table.getSubTable().getColumns()) {
				if (column.isPk()) {
					table.getSubTable().setPkColumn(column);
					break;
				}
			}
			if (StringUtils.isNull(table.getSubTable().getPkColumn())) {
				table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0));
			}
		}
	}

	/**
	 * 获取代码生成地址
	 * 
	 * @param table    业务表信息
	 * @param template 模板文件路径
	 * @return 生成地址
	 */
	public static String getGenPath(GenTable table, String template) {
		// String genPath = table.getGenPath();
		String genPath = "src";
		if (StringUtils.equals(genPath, "/")) {
			return System.getProperty("user.dir") + File.separator + "src" + File.separator
					+ VelocityUtils.getFileName(template, table);
		}
		return genPath + File.separator + VelocityUtils.getFileName(template, table);
	}
}
